package com.sky.controller.admin;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import com.github.pagehelper.Page;
import com.sky.constant.MessageConstant;
import com.sky.constant.RedisKeyConstant;
import com.sky.dto.UserBanDTO;
import com.sky.dto.UserOperationVerifyDTO;
import com.sky.dto.UserStatusUpdateDTO;
import com.sky.entity.Users;
import com.sky.exception.BaseException;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.UserBanService;
import com.sky.service.UserService;
import com.sky.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
 * 管理员用户管理相关接口
 */
@RestController
@RequestMapping("/admin/user")
@Slf4j
public class AdminUserManagementController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserBanService userBanService;

    /**
     * 分页查询用户列表
     *
     * @param page     页码
     * @param pageSize 每页记录数
     * @param name     用户名称
     * @return Result<PageResult>
     */
    @GetMapping("/page")
    @SaCheckPermission(value = "UserManagementRelated", orRole = {"SuperAdmin", "UserAdmin"})
    public Result<Page<Users>> page(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer pageSize,
            String name) {
        Page<Users> usersPage = userService.getUsersPage(page, pageSize, name);
        return Result.success(usersPage);
    }

    /**
     * 根据id查询用户详情
     *
     * @param userId 用户id
     * @return Result<UserVO>
     */
    @GetMapping("/{userId}")
    @SaCheckPermission(value = "UserManagementRelated", orRole = {"SuperAdmin", "UserAdmin"})
    public Result<UserVO> getById(@PathVariable Integer userId) {
        UserVO userVO = userService.getUserDetails(userId);
        return Result.success(userVO);
    }

    /**
     * 更新用户状态（封禁/解封）
     * 
     * @param userId 用户ID
     * @param statusUpdateDTO 状态更新信息
     *        status: 用户状态（0-正常，1-封禁）
     *        banReason: 封禁原因（封禁时必填）
     *        banDuration: 封禁时长（分钟）
     *        verificationCode: 验证码
     * @return Result
     * @throws BaseException VERIFICATION_CODE_EXPIRED 验证码已过期
     *                      VERIFICATION_CODE_ERROR 验证码错误
     *                      USER_NOT_FOUND 用户不存在
     *                      INVALID_STATUS 无效状态
     *                      BAN_REASON_REQUIRED 封禁需要原因
     *                      BAN_DURATION_INVALID 封禁时长无效
     *                      USER_ALREADY_BANNED 用户已被封禁
     *                      USER_NOT_BANNED 用户未被封禁
     *                      ADMIN_CANNOT_BE_BANNED 管理员不可封禁
     *                      CANNOT_BAN_SELF 不能封禁自己
     */
    @PutMapping("/status/{userId}")
    @SaCheckPermission(value = "UserManagementRelated", orRole = {"SuperAdmin", "UserAdmin"})
    public Result updateStatus(
            @PathVariable Integer userId,
            @RequestBody @Valid UserStatusUpdateDTO statusUpdateDTO) {

        log.info("更新用户状态，用户ID：{}，状态更新信息：{}", userId, statusUpdateDTO);

        // 获取验证码key
        String redisKey = statusUpdateDTO.getStatus() == 1 
            ? RedisKeyConstant.ADMIN_BAN_USER_CODE + StpUtil.getLoginIdAsInt() + ":" + userId
            : statusUpdateDTO.getStatus() == 0 
                ? RedisKeyConstant.ADMIN_UNBAN_USER_CODE + StpUtil.getLoginIdAsInt() + ":" + userId
                : null;

        if (redisKey == null) {
            throw new BaseException(MessageConstant.INVALID_STATUS);
        }

        // 校验验证码
        String storedCode = (String) redisTemplate.opsForValue().get(redisKey);
        if (storedCode == null) {
            throw new BaseException(MessageConstant.VERIFICATION_CODE_EXPIRED);
        }
        if (!storedCode.equals(statusUpdateDTO.getVerificationCode())) {
            throw new BaseException(MessageConstant.VERIFICATION_CODE_ERROR);
        }
        redisTemplate.delete(redisKey);

        // 执行状态更新
        UserBanDTO banDTO = new UserBanDTO();
        banDTO.setStatus(statusUpdateDTO.getStatus());
        
        // 封禁操作时设置封禁原因和时长
        if (statusUpdateDTO.getStatus() == 1) {
            if (statusUpdateDTO.getBanReason() == null) {
                throw new BaseException(MessageConstant.BAN_REASON_REQUIRED);
            }
            if (statusUpdateDTO.getBanDuration() == null || statusUpdateDTO.getBanDuration() <= 0) {
                throw new BaseException(MessageConstant.BAN_DURATION_INVALID);
            }
            banDTO.setReason(statusUpdateDTO.getBanReason());
            banDTO.setBanDuration(Math.toIntExact(statusUpdateDTO.getBanDuration()));
        }
        
        userBanService.updateUserStatus(userId, banDTO);
        return Result.success();
    }

    /**
     * 删除用户
     * 需要验证码验证
     *
     * @param userId    用户id
     * @param verifyDTO 验证码信息
     * @return Result
     */
    @DeleteMapping("/{userId}")
    @SaCheckPermission(value = "UserManagementRelated", orRole = {"SuperAdmin", "UserAdmin"})
    public Result deleteUser(
            @PathVariable Integer userId,
            @RequestBody @Valid UserOperationVerifyDTO verifyDTO) {

        log.info("删除用户:{},{}", userId, verifyDTO);

        // 验证验证码
        String redisKey = RedisKeyConstant.ADMIN_DELETE_USER_CODE + StpUtil.getLoginIdAsInt() + ":" + userId;
        String storedCode = (String) redisTemplate.opsForValue().get(redisKey);

        if (storedCode == null) {
            throw new BaseException(MessageConstant.VERIFICATION_CODE_EXPIRED);
        }

        if (!storedCode.equals(verifyDTO.getVerificationCode())) {
            throw new BaseException(MessageConstant.VERIFICATION_CODE_ERROR);
        }

        // 验证通过，删除验证码
        redisTemplate.delete(redisKey);

        // 删除用户
        userService.deleteUser(userId);
        return Result.success();
    }
} 